package com.nbcio.pm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nbcio.common.mybatis.core.page.PageQuery;
import com.nbcio.common.mybatis.core.page.TableDataInfo;
import com.nbcio.common.core.utils.MapstructUtils;
import com.nbcio.common.core.utils.StringUtils;
import com.nbcio.pm.domain.PmTask;
import com.nbcio.pm.domain.PmTaskDependency;
import com.nbcio.pm.domain.bo.PmTaskBo;
import com.nbcio.pm.domain.bo.PmTaskDependencyBo;
import com.nbcio.pm.domain.vo.PmTaskVo;
import com.nbcio.pm.domain.vo.PmTaskDependencyVo;
import com.nbcio.pm.mapper.PmTaskMapper;
import com.nbcio.pm.mapper.PmTaskDependencyMapper;
import com.nbcio.pm.service.IPmTaskService;
import com.nbcio.pm.service.impl.PmProjectValidationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 任务管理Service业务层处理
 *
 * @author nbacheng
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class PmTaskServiceImpl implements IPmTaskService {

    private final PmTaskMapper baseMapper;
    private final PmTaskDependencyMapper dependencyMapper;
    private final PmProjectValidationService validationService;

    /**
     * 查询任务列表
     */
    @Override
    public TableDataInfo<PmTaskVo> queryPageList(PmTaskBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PmTask> lqw = buildQueryWrapper(bo);
        Page<PmTaskVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询任务详细信息
     */
    @Override
    public PmTaskVo queryById(Long taskId) {
        return baseMapper.selectPmTaskById(taskId);
    }

    /**
     * 新增任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(PmTaskBo bo) {
        PmTask add = MapstructUtils.convert(bo, PmTask.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setTaskId(add.getTaskId());
        }
        return flag;
    }

    /**
     * 修改任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(PmTaskBo bo) {
        PmTask update = MapstructUtils.convert(bo, PmTask.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 删除任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 获取任务树结构
     */
    @Override
    public List<PmTaskVo> getTaskTree(Long projectId) {
        return baseMapper.selectTaskTree(projectId);
    }

    /**
     * 更新任务状态
     */
    @Override
    public Boolean updateTaskStatus(Long taskId, String status) {
        return baseMapper.updateTaskStatus(taskId, status) > 0;
    }

    /**
     * 分配任务
     */
    @Override
    public Boolean assignTask(Long taskId, Long assigneeId) {
        return baseMapper.assignTask(taskId, assigneeId) > 0;
    }

    /**
     * 获取用户任务列表
     */
    @Override
    public List<PmTaskVo> getUserTasks(Long userId, String status) {
        return baseMapper.selectUserTasks(userId, status);
    }

    /**
     * 获取任务依赖关系
     */
    @Override
    public List<PmTaskDependencyVo> getTaskDependencies(Long taskId) {
        return dependencyMapper.selectTaskDependencies(taskId);
    }

    /**
     * 添加任务依赖
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addTaskDependency(PmTaskDependencyBo bo) {
        // 检查依赖关系是否已存在
        Boolean exists = dependencyMapper.checkDependencyExists(bo.getPredecessorId(), bo.getSuccessorId());
        if (exists) {
            throw new RuntimeException("依赖关系已存在");
        }
        
        PmTaskDependency add = MapstructUtils.convert(bo, PmTaskDependency.class);
        return dependencyMapper.insert(add) > 0;
    }

    /**
     * 删除任务依赖
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeTaskDependency(Long dependencyId) {
        return dependencyMapper.deleteById(dependencyId) > 0;
    }

    private LambdaQueryWrapper<PmTask> buildQueryWrapper(PmTaskBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PmTask> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getProjectId() != null, PmTask::getProjectId, bo.getProjectId());
        lqw.like(StringUtils.isNotBlank(bo.getTaskName()), PmTask::getTaskName, bo.getTaskName());
        lqw.like(StringUtils.isNotBlank(bo.getTaskCode()), PmTask::getTaskCode, bo.getTaskCode());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), PmTask::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getPriority()), PmTask::getPriority, bo.getPriority());
        lqw.eq(bo.getAssigneeId() != null, PmTask::getAssigneeId, bo.getAssigneeId());
        lqw.eq(bo.getParentId() != null, PmTask::getParentId, bo.getParentId());
        
        // 安全地处理params，避免空指针异常
        if (params != null) {
            lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
                    PmTask::getCreateTime, params.get("beginTime"), params.get("endTime"));
        }
        
        lqw.orderByAsc(PmTask::getSortOrder).orderByDesc(PmTask::getCreateTime);
        return lqw;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PmTask entity) {
        // TODO 做一些数据校验,如唯一约束
        
        // 验证任务负责人是否为项目成员
        if (entity.getProjectId() != null && entity.getAssigneeId() != null) {
            if (!validationService.validateTaskAssignee(entity.getProjectId(), entity.getAssigneeId())) {
                log.warn("任务负责人 {} 不是项目 {} 的成员", entity.getAssigneeId(), entity.getProjectId());
                // 这里可以选择抛出异常或仅记录警告
                // throw new ServiceException("任务负责人必须是项目成员");
            }
        }
        
        // 验证任务报告人是否为项目成员
        if (entity.getProjectId() != null && entity.getReporterId() != null) {
            if (!validationService.validateTaskReporter(entity.getProjectId(), entity.getReporterId())) {
                log.warn("任务报告人 {} 不是项目 {} 的成员", entity.getReporterId(), entity.getProjectId());
                // 这里可以选择抛出异常或仅记录警告
                // throw new ServiceException("任务报告人必须是项目成员");
            }
        }
    }
}
